#include "descr_parser.h"

#include <fstream>
#include <iostream>
#include <sstream>
#include <OgreTextureManager.h>
#include "util.h"
#include "region.h"


using namespace std;


const string DescrParser::DELIMITERS = "\t ,";
const string DescrParser::COMMA      = ",";


bool DescrParser::open(string filepath)
{
	bool isSuccessful = false;

	ifstream inputStream(filepath);
	if (inputStream.is_open()) 
	{
		while (inputStream.good())
		{
			string line;
			getline(inputStream, line);

			size_t i = line.find_first_of(";");
			if (i != string::npos)
			{
				line.erase(i);
			}

			if (line.length() > 0)
			{
				isSuccessful = parse(line);
				if (!isSuccessful)
				{
					break;
				}
			}
		}
		inputStream.close();
	}
	else
	{
		cerr << "Could not open file: " << filepath << endl;
	}
	return isSuccessful;
}


void DescrParser::setBasePath(string path)
{
	this->basePath = path;
}


string DescrParser::popNextToken(string& str)
{
	return Util_popNextToken(str, DELIMITERS);
}


string DescrParser::popNextToken(string& str, const string& delimiters)
{
	return Util_popNextToken(str, delimiters);
}


bool GroundTypesParser::parse(string line)
{
	bool isSuccessful = false;
	string token = popNextToken(line);
	if (token.compare("climate") == 0)
	{
		string climateName = popNextToken(line);
		if (climateName.length() > 0)
		{
			parsingClimate = Climate::getClimate(climateName);
			isSuccessful = true;
		}
	}
	else
	{
		GroundType::Index groundTypeIndex = GroundType::get(token);
		if (groundTypeIndex != GroundType::INVALID)
		{
			string textureFileName = popNextToken(line);
			if (textureFileName.length() > 0)
			{
				parsingClimate->textures[Season::SUMMER][groundTypeIndex] = textureFileName;

				string nextTextureFileName = popNextToken(line);
				if (nextTextureFileName.length() > 0)
				{
					textureFileName = nextTextureFileName;
				}
				parsingClimate->textures[Season::WINTER][groundTypeIndex] = textureFileName;
				isSuccessful = true;
			}
		}
		else
		{
			isSuccessful = true;
		}
	}
	return isSuccessful;
}


bool ClimatesParser::parse(string line)
{
	bool isSuccessful = false;
	string token = popNextToken(line);
	if (token.compare("climate") == 0)
	{
		string climateName = popNextToken(line);
		if (climateName.length() > 0)
		{
			shared_ptr<Climate> climate(new Climate());
			climate->name = climateName;
			parsingClimate = climate;
			isSuccessful = true;
		}
	}
	else if (token.compare("colour") == 0)
	{
		unsigned int color = 0;
		for (int i = 0; i < 3; i++)
		{
			unsigned int channel;
			istringstream buffer(popNextToken(line));
			buffer >> channel;
			color = (color << 8) | ((unsigned char) channel);
		}
		parsingClimate->color = color | 0xff000000;
		Climate::add(parsingClimate);
		isSuccessful = true;
	} 
	else if (token.compare("strategy") == 0)
	{
		string seasonName = popNextToken(line);
		Season::Index seasonIndex = Season::seasonsMap[seasonName].getIndex();

		string treeType = popNextToken(line);
		if (treeType.compare("sparse_tree") == 0)
		{
			string fileName = popNextToken(line);
			shared_ptr<Cas> cas = Cas::get(basePath + fileName, Cas::Type::RTW);
			parsingClimate->sparseTree[seasonIndex] = cas;
		}
		else if (treeType.compare("dense_tree") == 0)
		{
			string fileName = popNextToken(line);
			shared_ptr<Cas> cas = Cas::get(basePath + fileName, Cas::Type::RTW);
			parsingClimate->denseTree[seasonIndex] = cas;
		}
		else if (treeType.compare("canopy") == 0)
		{
			string fileName = popNextToken(line);
			shared_ptr<Cas> cas = Cas::get(basePath + fileName, Cas::Type::RTW);
			parsingClimate->canopy[seasonIndex] = cas;
		}

		isSuccessful = true;
	}
	else
	{
		isSuccessful = true;
	}
	return isSuccessful;
}
